package cn.witsky.rtp2ws.client.ws;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.witsky.rtp2ws.Server;
import cn.witsky.rtp2ws.client.ws.netty.Netty;
import cn.witsky.rtp2ws.client.ws.netty.NettyChannelFutureListener;
import cn.witsky.rtp2ws.client.ws.netty.NettyClient;
import cn.witsky.rtp2ws.domain.Rtp;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;

public class Client {
	private static Logger logger = LoggerFactory.getLogger(Client.class);
	public static boolean useNetty = true;
	WsClient wsClient = null;
	Channel channel = null;
	Rtp rtp;
	ChannelFutureListener channelFutureListener = null;
	private boolean isValid=true;
	
	private Client(Rtp rtp) {
		this.rtp = rtp;
		channelFutureListener = new NettyChannelFutureListener(this.rtp);		
	}

	public static Client getInstance(Rtp rtp, boolean retry) {
		Client client = new Client(rtp);
		if (!useNetty) {
			client.wsClient = WsClient.getWsClient(rtp, retry);
		} else {
			Channel channel= Netty.getWsClient(rtp, retry);
			if(channel!=null) {
				NettyClient.addNettyClient(rtp.getRtpId(),channel);
			}else {
				client.setValid(false);
			}			
			client.channel =channel;			
		}
		logger.debug("创建client:{},channel:{}", rtp.getRtpId(), client.channel);
		return client;
	}

//	public boolean  sendBinary() {
//		ByteBuf bf=this.rtp.getRtpCache().bufRead();
//		if(bf!=null) {
//			rtp.setLastSendTime();
//			return true;
//		}else {
//			return false;
//		}
//
//		
//	}
//	public boolean  sendEndFlag() {
//		rtp.setLastSendTime();
//		this.rtp.getRtpCache().bufRelease(rtp.getRtpId());
//		return true;
//		
//	}
	public boolean  sendBinary() {
		try {	
			int byteSize=this.rtp.getRtpCache().getByteSzie();
			if(byteSize==0) {
				return false;
			}
			byte[] bytes=new byte[byteSize];		
			this.rtp.getRtpCache().bufRead(bytes);
			if(bytes==null||bytes.length==0) {
				return false;
			}
			if (!useNetty) {
				wsClient.send(bytes);
			} else {			
				if(channel==null) {
					return false;
				}else {		
				    BinaryWebSocketFrame binaryWebSocketFrame = new BinaryWebSocketFrame(Unpooled.wrappedBuffer(bytes));
					channel.writeAndFlush(binaryWebSocketFrame).addListener(channelFutureListener);
				}
			}
			rtp.setLastSendTime();
			return true;
		}catch(Exception ex) {
			logger.error("wsClient"+this.rtp.getRtpId()+"发送数据出现异常", ex);
			return false;
		}		
	}
	
	
	public boolean  sendEndFlag() {
		try {
			if (!useNetty) {
				wsClient.send(Server.endFlag.getBytes());
			} else {			
				if(channel==null) {
					return false;
				}else if (!channel.isOpen()) {
					logger.warn("client:{}的channel被关闭了。。。。。。。",this.rtp.getRtpId());
					return false;
				}else {		
					ByteBuf bf=Unpooled.wrappedBuffer(Server.endFlag.getBytes());
				    BinaryWebSocketFrame binaryWebSocketFrame = new BinaryWebSocketFrame(bf);
					channel.writeAndFlush(binaryWebSocketFrame).addListener(channelFutureListener);
				}
			}
			rtp.setLastSendTime();
			this.rtp.getRtpCache().bufRelease(this.rtp.getRtpId());
			return true;
		}catch(Exception ex) {
			logger.error("wsClient"+this.rtp.getRtpId()+"发送数据出现异常", ex);
			return false;
		}
		
	}
	
	public void addListener(ClientListener wsListener) {
		if (!useNetty) {
			wsClient.addListener(wsListener);
		} else {
			NettyClient client=NettyClient.getNettyClient(channel);
			if(client!=null) {
				client.setWsListener(wsListener);
			}
		}
	}

	public ClientListener getWsListener() {
		if (!useNetty) {
			return wsClient.getWsListener();
		} else {
			NettyClient client=NettyClient.getNettyClient(channel);
			if(client!=null) {
				return client.getWsListener();
			}else {
				return null;
			}
			
		}
	}

	public void setSubscribe(boolean subscribe) {
		if (!useNetty) {
			wsClient.setSubscribe(subscribe);
		} else {
			NettyClient client=NettyClient.getNettyClient(channel);
			if(client!=null) {
				client.setSubscribe(subscribe);
			}
		}
	}

	public void close() {		
		try {
			if (!useNetty) {
				logger.info("关闭wsClient:{}......",this.rtp.getRtpId());
				wsClient.close();
			} else {
				NettyClient client = NettyClient.getNettyClient(channel);
				if(client!=null) {
					client.setSubscribe(false);
					client.setWsListener(null);
				}	
				
				channel.writeAndFlush(new CloseWebSocketFrame()).addListener(ChannelFutureListener.CLOSE);
			}
		}catch(Exception ex) {
			logger.error("wsClient"+this.rtp.getRtpId()+"关闭出现异常", ex);
		}

	}

//	
//	public void close() {		
//		if (!useNetty) {
//			logger.info("关闭wsClient:{}......",this.rtp.getRtpId());
//			wsClient.close();
//		} else {
//			NettyClient client = NettyClient.getNettyClient(channel);
//			if(client!=null) {
//				client.setSubscribe(false);
//				client.setWsListener(null);
//			}		
//			if(channel.isActive()) {
//				ChannelFuture future=channel.writeAndFlush(new CloseWebSocketFrame());
//				try {
//					future.get();
//				} catch (Exception e) {
//					logger.error("向netty-wsClient:" + this.rtp.getRtpId() + "发是websocketClose异常", e);
//				}
//				try {
//					if (channel.isActive()) {
//						logger.info("channel未关闭，主动关闭netty-wsClient:{}......", this.rtp.getRtpId());
//						channel.disconnect();
//						channel.close();
//					} else {
//						logger.info("netty-wsClient:{}已经被关闭了......", this.rtp.getRtpId());
//					}
//				} catch (Exception ex) {
//					logger.error("关闭netty-wsClient:" + this.rtp.getRtpId() + "出现异常", ex);
//				}
//			} else {
//				logger.info("netty-wsClient:{}已经被关闭了......", this.rtp.getRtpId());
//			}
//		}
//	}
	
	public void connectBlocking() throws InterruptedException {
		if (!useNetty) {
			wsClient.connectBlocking();
		}
	}

	public boolean isValid() {
		return isValid;
	}

	public void setValid(boolean isValid) {
		this.isValid = isValid;
	}
}
